package view.layer
{
	import control.manager.BitmapManager;
	import control.manager.LayerManager;
	import control.manager.MapManager;
	import control.manager.RoleManager;
	import control.manager.TaskManager;
	import control.util.AStarPathFinder;
	import control.util.CustomLoader;
	import control.util.GameUtil;
	
	import data.BitmapItem;
	import data.ExitsData;
	import data.GameConst;
	import data.MapData;
	import data.MonsterData;
	import data.NPCData;
	import data.PlayerData;
	import data.TaskVO;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;
	
	import view.item.ExitsView;
	import view.item.MapTileItem;
	import view.role.MapMonster;
	import view.role.MapNPC;
	import view.role.MapObject;
	import view.role.MapPlayer;
	import view.stage.StageGame;
	import view.ui.UIMain;
	import view.ui.UIPopupLayer;
	import view.ui.UITaskList;

	/**
	 * 地图层(有两层，马赛克层和清晰层)
	 * @author leo
	 * 
	 */	
	public class MapLayer extends BaseLayer
	{
		/**
		 * 层名字 
		 */		
		public static const NAME :String = "MAP_LAYER";
		/**
		 * 地图位图(马赛克层)
		 */		
		public var mapBitmap :Bitmap;
		
		/**
		 * 清晰层 
		 */		
		public var distinctLayer :Sprite;
		/**
		 * 当前这张地图的传送点列表 
		 */		
		public var exitsViewList :Vector.<ExitsView>;
		
		/**
		 * 清晰层的显示区域 
		 */		
		public var visibleRect :Rectangle;
		/**
		 * 当前地图数据 
		 */		
		public var curMapData :MapData;
		/**
		 * 当前舞台可视范围宽
		 */		
		public var visbleW :int;
		/**
		 * 当前舞台可视范围高
		 */		
		public var visbleH :int;
		/**
		 * 缩略图 
		 */		
		private var thumbnail :MapTileItem;
		/**
		 * 人物点 
		 */		
		private var heroPoint :Point;
		/**
		 * 地图区块数组 （用于是否加载时判断是否超出索引范围）（300×300一张的区块）
		 */		
		private var mapAry :Array;
		/**
		 * 加载的是否是缩略图（0否，1是） 
		 */		
		private var isThumbnail :int;
		/**
		 * 网格层 
		 */		
		private var gridLayer :GridLayer;
		/**
		 * 所有图块的uid值 (用于检测是否需要显示图块，超出可视区域)
		 */		
		private var allItemUidList :Array;
		/**
		 * 当前可视区域内的地图块UID值 
		 */		
		private var visibleItemUidList :Array;
		public function MapLayer()
		{
			super();
			this.mapBitmap = new Bitmap();
			this.addChild(this.mapBitmap);
			this.distinctLayer = new Sprite();
			this.addChild(distinctLayer);
		}
		/**
		 * 转换地图 
		 * @param mapID 地图ID
		 * @param heroPoint 人物坐标点
		 * @param visbleW 当前舞台可视范围宽
		 * @param visbleH 当前舞台可视范围宽
		 * 
		 */		
		public function changeMap(mapData :MapData,visbleW :int,visbleH :int):void
		{
			this.curMapData = mapData;
			if(!this.curMapData)
			{
				trace("at MapLayer 没有当前地图数据");
				return;
			}
			//网格
			if(GameConst.isShowGrid)
			{
				if(this.gridLayer)
				{
					this.removeChild(this.gridLayer);
					this.gridLayer = null;
				}
				this.gridLayer = new GridLayer(this.curMapData);
				this.gridLayer.x = -30;
				this.gridLayer.y = -15;
				this.addChild(gridLayer);
			}
			//清空图缓存的地图块
			BitmapManager.instance.clearMapCache();
			
			this.visbleW = visbleW;
			this.visbleH = visbleH;
			this.mapAry = this.getMapAry();
			if(!this.mapAry || this.mapAry.length == 0)
			{
				trace("at MapLayer 没有当前地图数组数据");
				return;
			}
			//开始加载小图
			var uid :String = "map" + "_" + this.curMapData.mapID + "_" + "pre";
			var item :MapTileItem = BitmapManager.instance.findMapTileItem(uid);
			if(!item)
			{
				this.thumbnail =  new MapTileItem(this.curMapData,0,0,1);
				GameUtil.instance.checkIsTrue(thumbnail,"isComplete",thumbnailIsComplete);
			}else
			{
				this.thumbnail = item;
				thumbnailIsComplete();
			}
			//设置npc,monster需要用到的uid随机值
			GameUtil.instance.setRandom();
			
			//初始化寻路节点信息
			MapManager.instance.initNodeGrid(mapData);
			
			var mainUI :UIMain = LayerManager.instance.getLayer(UIMain.NAME) as UIMain;
			if(mainUI)
			{
				//切换地图重新设置小地图
				mainUI.miniMapUI.sceneNameTxt.text = mapData.mapName;
				mainUI.miniMapContainer.initMiniMap();
			}
			
			//设置角色层的长宽
			var roleLayer :RoleLayer = LayerManager.instance.getLayer(RoleLayer.NAME) as RoleLayer;
			roleLayer.width = mapData.mapWidth;
			roleLayer.height = mapData.mapHeight;
			
			
			//获取当前地图图块的uid值
			this.allItemUidList = getItemUidList();
			
			//更新地图数据
			MapManager.instance.curMapData = mapData;
		}
		
		/**
		 * 加载小图完成 
		 * @param data
		 * 
		 */		
		private function thumbnailIsComplete(data :* = null):void
		{
			this.mapBitmap.bitmapData = this.thumbnail.bitmapData;
			this.mapBitmap.width = this.curMapData.mapWidth;
			this.mapBitmap.height = this.curMapData.mapHeight;
			
			this.moveArea = new Rectangle(this.x,this.y,this.width,this.height);
			while(this.distinctLayer.numChildren > 0)
			{
				this.distinctLayer.removeChildAt(0);
			}
			if(player && player.gameLayer)
			{
				player.gameLayer.lockAt(player.x,player.y);
				player.curClickObj = null;
			}
			
			//是否需要加载地图块
			checkAndLoadMapTileItem(true);
			//初始化传送点
			initExitsView();
			//初始化npc
			initNPC();
			//初始化怪物
			initMonster();
			
			//排序
			var roleLayer :RoleLayer = LayerManager.instance.getLayer(RoleLayer.NAME) as RoleLayer;
			var roleList :Array = RoleManager.instance.roleList;
			RoleManager.instance.sortY(roleLayer,roleList);
			
			//是否第一次进入游戏弹任务窗
			UIPopupLayer.I.firstTaskShow();
			
			//玩家有任务数据时
			var pd :PlayerData = RoleManager.instance.playerData;
			if(pd && pd.taskingList.length > 0)
			{
				RoleManager.instance.changeNpcStatus();
			}
			
			//设置可接任务的NPC的状态
			var list :Array = TaskManager.instance.findCanAcceptTaskList();
			for each(var taskVO :TaskVO in list)
			{
				if(taskVO)
				{
					var npc :MapNPC = RoleManager.instance.findNPCByID(taskVO.sendNPCID);
					if(npc)
					{
						npc.setTaskStatus(GameConst.HAVE_TASK);
					}
				}
			}
			//记录切换的地图ID到玩家数据中
			pd.curMapID = this.curMapData.mapID;
			
			//切换地图后如果有需要寻找的NPC或怪物则自动去寻找
			var needWalkPoint :Array = RoleManager.instance.needWalkPoint;
			if(needWalkPoint && needWalkPoint.length > 0)
			{
				var obj :Object = needWalkPoint.shift();
				if(obj is ExitsData)
				{
					var ed :ExitsData = obj as ExitsData;
					player.findPath(player.position,ed.exitsPosition);
				}else
				{
					var id :String = obj as String;
					if(id.indexOf("npc") != -1)
					{
						var mapNPC :MapNPC = RoleManager.instance.findNPCByID(id);
						if(mapNPC)
						{
							//模拟一次点击npc
							player.onClick(mapNPC);
						}else
						{
//							//如果没有找到NPC，检查下是否需要是其他地图的NPC
//							RoleManager.instance.isNeedChangeMapByNPC(id);
						}
					}else if(id.indexOf("monster") != -1)
					{
						var monster :MapMonster = RoleManager.instance.findMonsterByID(id);
						if(monster)
						{
							var player :MapPlayer = RoleManager.instance.player;
							if(player)
							{
								player.onClick(monster);
							}
						}else
						{
//							//如果没有找到怪物，检查下是否需要是其他地图的怪物
//							RoleManager.instance.isNeedChangeMapByMonster(id);
						}
					}
				}
			}
			
			//隐藏Loading界面
			UIPopupLayer.I.hideLoading();
			
		}
		/**
		 * 初始化怪物 
		 * 
		 */		
		private function initMonster():void
		{
			var monsterDataList :Vector.<MonsterData> = this.curMapData.monsterDataList;
			var roleList :Array = RoleManager.instance.roleList;
			if(monsterDataList && monsterDataList.length > 0)
			{
				for each(var monsterData :MonsterData in monsterDataList)
				{
					if(monsterData.monsterNumber > 0)
					{
						var pAry :Array = RoleManager.instance.getAroundPoint(monsterData);
						if(pAry.length == 0) return;
						for(var i :int = 0 ; i < pAry.length; i++)
						{
							var mapMonster :MapMonster = new MapMonster(monsterData);
							var w :int = this.curMapData.mapWalkGapWidth;
							var h :int = this.curMapData.mapWalkGapHeight;
							var px :int = (pAry[i] as Point).x;
							var py :int = (pAry[i] as Point).y;
							var bornPoint :Point = MapManager.instance.getPixelPoint(w,h,px,py);
							mapMonster.x = bornPoint.x;
							mapMonster.y = bornPoint.y;
							RoleManager.instance.addRole(mapMonster);
							mapMonster.mouseCollision.refreshRectangle();
						}
					}
				}
			}
		}
		/**
		 * 初始化NPC 
		 * 
		 */		
		private function initNPC():void
		{
			//npc 
			var npcDataList :Vector.<NPCData> = curMapData.npcDataList;
			var roleList :Array = RoleManager.instance.roleList;
			if(npcDataList && npcDataList.length > 0)
			{
				for each(var npcData :NPCData in npcDataList)
				{
					var mapNPC :MapNPC = new MapNPC(npcData);
					var w :int = this.curMapData.mapWalkGapWidth;
					var h :int = this.curMapData.mapWalkGapHeight;
					var px :int = npcData.npcPosition.x;
					var py :int = npcData.npcPosition.y;
					var bornPoint :Point = MapManager.instance.getPixelPoint(w,h,px,py);
					mapNPC.x = bornPoint.x;
					mapNPC.y = bornPoint.y;
					mapNPC.npcData.taskList = TaskManager.instance.findCurNPCTask(npcData.npcID);
					RoleManager.instance.addRole(mapNPC);
					mapNPC.mouseCollision.refreshRectangle();
				}
			}
		}
		/**
		 * 初始化传送点 
		 */		
		private function initExitsView():void
		{
			//初始化 传送点
			if(this.curMapData.exitsDataList.length > 0)
			{
				var dataList :Vector.<ExitsData> = this.curMapData.exitsDataList;
				var exitsView :ExitsView;
				//切换地图时如果有上一张地图的传送点的话就删除
				if(this.exitsViewList && this.exitsViewList.length > 0)
				{
					for(var i :int = this.exitsViewList.length - 1; i >= 0; i--)
					{
						exitsView = (this.exitsViewList[i] as ExitsView);
						this.removeChild(exitsView);
					}
					this.exitsViewList = null;
				}
				this.exitsViewList = new Vector.<ExitsView>();
				
				for each(var exitsData :ExitsData in dataList)
				{
					exitsView = new ExitsView(exitsData,this.curMapData);
					this.addChild(exitsView);
					this.exitsViewList.push(exitsView);
				}
			}
		}
		/**
		 *  返回当前地图的数据（用于是否加载时判断是否超出索引范围）
		 * @return Array
		 * 
		 */		
		private function getMapAry():Array
		{
			var result :Array = [];
			var rows :int = this.curMapData.mapRows;
			var cols :int = this.curMapData.mapCols;
			for(var row :int = 0; row < rows ; row++)
			{
				result.push([]);
				for(var col :int = 0; col < cols; col++)
				{
					result[row][col] = true;
				}
			}
			return result;
				
		}
		/**
		 * 检查需要加载的图块 
		 * @param isChangeMap 是否是切换地图
		 * 
		 */		
		public function checkAndLoadMapTileItem(isChangeMap :Boolean = false):void
		{
			//计算当前可视范围应该加载几个地图块
			var mapTileWidth :int = this.curMapData.mapTileWidth;
			var mapTileHeight :int = this.curMapData.mapTileHeight;
			var stagePoint :Point =  this.globalToLocal(new Point(0,0));
			var visblePoint :Point = new Point(this.visbleW,this.visbleH);
			var startRow :int = stagePoint.y/mapTileHeight;
			var startCol :int = stagePoint.x/mapTileWidth;
			var endRow :int = (stagePoint.y + visblePoint.y)/mapTileHeight;
			var endCol :int = (stagePoint.x + visblePoint.x)/mapTileWidth;
			this.visibleItemUidList = [];
			for(var rows :int = startRow; rows <= endRow; rows++)
			{
				for(var cols :int = startCol;  cols <= endCol; cols++)
				{
					//如果超出数组索引就跳出
					if(rows >= this.mapAry.length || cols >= this.mapAry[0].length) break;
					
					if(this.mapAry[rows][cols])
					{
						//map_1002_0_0
						var uid :String = "map" + "_" + this.curMapData.mapID + "_" + rows + "_" + cols;
						var item :MapTileItem = BitmapManager.instance.findMapTileItem(uid);
						if(!item)
						{
							var mapTileItem :MapTileItem = new MapTileItem(this.curMapData,rows,cols);
							this.distinctLayer.addChild(mapTileItem);
							this.visibleItemUidList.push(uid);
							trace(uid);
						}else
						{
							//如果有缓存，而且是切换地图的话，直接拿缓存的来用
							if(isChangeMap)
							{
								this.distinctLayer.addChild(item);
							}
							//重新显示被隐藏的图块
							item.visible = true;
						}
					}else
					{
						trace(rows,cols + "at MapLayer 超出地图索引");
					}
				}
			}
		}
		
		/**
		 * 检查是否需要隐藏不在显示区域内的图块 
		 * 
		 */		
		public function checkAndRemoveMapTileItem():void
		{
			var mapTileItemList :Vector.<MapTileItem> = BitmapManager.instance.mapTileItemList;
			for each(var item :MapTileItem in mapTileItemList)
			{
				if(item.isThumbnail) continue;
				if(!item.visible) continue;
				if(this.visibleItemUidList.length == 0) return;
					
				if(this.visibleItemUidList.indexOf(item.uid) != -1)
				{
					
				}else
				{
					item.visible = false;
					trace("visible false " + item.uid);
				}
			}
			
			
		}
		/**
		 * 每次切换地图时都获取改地图所有图块的UID值 
		 * @return 
		 * 
		 */		
		private function getItemUidList():Array
		{
			var mapRows :int = this.curMapData.mapRows;
			var mapCols :int = this.curMapData.mapCols;
			var result :Array = [];
			for(var row :int = 0; row < mapRows; row++)
			{
				for(var col :int = 0; col < mapCols; col++)
				{
					var uid :String = "map" + "_" + this.curMapData.mapID + "_" + row + "_" + col;
					result.push(uid);
				}
			}
			
			if(result.length > 0)
			{
				return result;
			}
			
			return null;
		}
		
		private function get player():MapPlayer
		{
			var gameLayer :GameLayer = LayerManager.instance.getLayer(GameLayer.NAME) as GameLayer;
			if(gameLayer)
			{
				var player :MapPlayer = gameLayer.player;
				if(player)
				{
					return player;
				}
			}
			
			return null;
		}
		
	}
}